﻿using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using Deepforest.WPF.Controls.Data;

namespace Deepforest.WPF.Controls
{
	public class PropertyGrid : Control
	{
		static PropertyGrid()
		{
			DefaultStyleKeyProperty.OverrideMetadata(typeof(PropertyGrid),
				new FrameworkPropertyMetadata(typeof(PropertyGrid)));
		}

		#region Instance Property

		/// <value>Identifies the Instance dependency property</value>
		public static readonly DependencyProperty InstanceProperty =
			DependencyProperty.Register("Instance", typeof(object), typeof(PropertyGrid),
			new FrameworkPropertyMetadata(null, OnInstanceChanged, CoerceInstance));

		/// <value>description for Instance property</value>
		public object Instance
		{
			get { return (object)GetValue(InstanceProperty); }
			set { SetValue(InstanceProperty, value); }
		}

		/// <summary>
		/// Invoked on Instance change.
		/// </summary>
		/// <param name="d">The object that was changed</param>
		/// <param name="e">Dependency property changed event arguments</param>
		static void OnInstanceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			PropertyGrid propertyGrid = d as PropertyGrid;
			if (e.NewValue == null)
			{
				propertyGrid.Properties = new ObservableCollection<Item>();
			}
			else
			{
				PropertyCollection properties = new PropertyCollection(e.NewValue);
				propertyGrid.Properties = properties.Items;
			}
		}

		static object CoerceInstance(DependencyObject d, object value)
		{
			PropertyGrid propertyGrid = d as PropertyGrid;
			if (value == null)
			{
				return propertyGrid.NullInstance;
			}
			return value;
		}

		#endregion

		#region NullInstance Property

		/// <value>Identifies the NullInstance dependency property</value>
		public static readonly DependencyProperty NullInstanceProperty =
			DependencyProperty.Register("NullInstance", typeof(object), typeof(PropertyGrid),
			new FrameworkPropertyMetadata(null, OnNullInstanceChanged));

		/// <value>description for NullInstance property</value>
		public object NullInstance
		{
			get { return (object)GetValue(NullInstanceProperty); }
			set { SetValue(NullInstanceProperty, value); }
		}

		/// <summary>
		/// Invoked on NullInstance change.
		/// </summary>
		/// <param name="d">The object that was changed</param>
		/// <param name="e">Dependency property changed event arguments</param>
		static void OnNullInstanceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
		}

		#endregion

		#region Properties Property

		/// <value>Identifies the Properties dependency property</value>
		public static readonly DependencyProperty PropertiesProperty =
			DependencyProperty.Register("Properties", typeof(ObservableCollection<Item>), typeof(PropertyGrid),
			new FrameworkPropertyMetadata(new ObservableCollection<Item>(), OnPropertiesChanged));

		/// <value>description for Properties property</value>
		public ObservableCollection<Item> Properties
		{
			get { return (ObservableCollection<Item>)GetValue(PropertiesProperty); }
			set { SetValue(PropertiesProperty, value); }
		}

		static void OnPropertiesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			PropertyGrid propertyGrid = d as PropertyGrid;
			ObservableCollection<Item> properties = e.OldValue as ObservableCollection<Item>;
			foreach (Item item in properties)
			{
				item.Dispose();
			}
		}

		#endregion
	}
}
